Sed awk
De Wiki de Nelly & Richard.
Sommaire |
Expressions régulières
- Les expressions régulières sont utiles au quotidien dans l'utilisation de scripts, de programmation, egrep, ...
- Voici quelques outils qui vous aideront pour la réalisation de scripts.
Le caractère d'échappement \
- Le back-slash permet de désigner les caractères spécifiques suivant : . * ^ $ \ [ ]
exemple : $ echo 'c:\' | grep '\\' > nous renvoi bien c:\
Le point . et l'astérisque *
- Le point est aussi appelé caractère joker, il permet de remplacer n'importe quel caractère.
exemple : $ echo "test" | grep 't.st' > nous renvoi bien test
- L'astérisque lui va nous permettre de désigner 0, 1 ou plusieurs occurrences du caractère précédent
exemple : $ echo "ttttttt" | grep 't*' > nous renvoi bien ttttttt de même : $ echo "test" | grep 'tei*st' > nous renvoi bien test
L'accent circonflexe ^ et dollar $
- Ces deux caractères indique respectivement le début et la fin d'une ligne
exemple : $ echo "test" | grep '^test$' > nous renvoi bien test à l'inverse $ echo "test" | grep '^tes$' > ne renvoi rien
- Il peuvent rechercher une ligne vide : '^$'
Les crochets [ ] pour l'alternative
- Les crochets permettent de définir le ou logique
exemple : $ echo "test" | grep 't[ei]st' > renvoi test de même : $ echo "tist" | grep 't[ei]st' > renvoi tist ou : $ echo "teist" | grep 't[ei]*st' > renvoi teist
- Le tiret - permet de définir une plage (les chiffres de 2 à 7 -> [2-7])
exemple : $ echo "tEst" | grep 't[a-fA-F]st' > renvoi tEst
Les crochets [^ ] pour la négation
- Les crochets utilisés avec l'accent circonflexe permettent d'exprimer la négation
exemple : $ echo "test" | grep 't[^e]st' > ne renvoi rien
de même : $ echo "tist" | grep 't[^e]st' > renvoi tist
Les parenthèses \( \) pour les groupes
- Les parenthèses permettent d'isoler un groupe de caractères pour le rappeler éventuellement, l'exemple qui suit utilise sed nous verrons plus en détail les possibilité de cette commande plus bas.
exemple : $ echo "Quel beau paysage" | sed -e 's/^\(Quel beau\).*$/\1 tableau/' > renvoi : Quel beau tableau
Les éléments compris entre \( \) sont rappelés avec \1, \2 si il y a 2 sous ensemble, ...
Les accolades \{ \}
- Les accolades définissent le nombre d'occurrences du caractère, sous ensemble ou alternative qui les précèdent.
exemple : $ echo "teeest" | grep 'te\{3\}st' > renvoi : teeest
- Comme les parenthèses les accolades sont utilisées avec les back-slash \{ \}
sed
- Sed permet d'effectuer des manipulations simples sur des fichiers textes. Vous trouverez des informations dans la manpage de sed ou l'infopage de sed répondront à toutes vos questions.
- dans les exemples qui suivent j'utiliserais ce fichier sed.txt :
azerty AZERTY 01234 azErty0uiOp3qsdf6 a z e r t y a/z/e/r/t/y blabla bla bla bla
options
- -i : enregistre les modifications dans le fichier traité.
sed -i 'expression' fichier
- -e : permet d'appeler plusieurs commandes à la suite.
sed -e 'expression' -e 'expression' fichier
- -n : silencieux utilise avec p.
# même comportement qu'un cat sed -n 'p' fichier
- -f : utilisation d'un fichier script.
le format du fichier script est :
'expression' 'expression' ... # usage : sed -f file-script fichier
expressions
syntaxe
- De manière générale :
'<début_recherche>,<fin_recherche><commande>'
- <début_recherche> et <fin_recherche> peuvent-être des numéros de ligne ou bien des expressions régulière.
- plusieurs <commande> peuvent être placées.
sed -n '2,/[0-9]/p' sed.txt # recherchera à partir de la 2° ligne jusqu'au prochain caractère numérique # renvoie : AZERTY 01234
subtitution
Elle doit-être de loin la plus connue vous l'utilisez peut-être déjà avec vim
- syntaxe : 's/<expression régulière>/<chaîne de remplacement>/'
- exemple :
sed -n '2,/[0-9]/s/[0-9]/Number/p' sed.txt # renvoie : Number1234
- vous pouvez spécifier une sous-chaîne et la rappeler dans la chaîne de remplacement \n
- exemple :
sed -n '2s/\(AZ\)E/\1@/p' sed.txt # renvoie : AZ@RTY
suppression
divers
- g : répète la commande tant que le texte recherché est trouver.
- exemple :
sed -n 's/a/@/pg' sed.txt # renvoie : @zerty @zErty0uiOp3qsdf6 @ z e r t y @/z/e/r/t/y bl@bl@ bl@ bl@ bl@
- i : ignore la casse
- exemple :
sed -n 's/a/@/pgi' sed.txt @zerty @ZERTY @zErty0uiOp3qsdf6 @ z e r t y @/z/e/r/t/y bl@bl@ bl@ bl@ bl@
awk
- Awk est un langage qui permet également la manipulation de chaînes de caractères et/ou de fichiers texte. En l'utilisant de façon avancée vous obtiendrez la puissance d'un tableur.
- Ce qui suit est vraiment un survol des possibilités de g(awk), la manpage de awk ainsi que les liens en bas de page vous permettrons d'en savoir d'avantage.
- pour les exemples qui vont suivre nous utiliserons le fichier généré aléatoirement : awk_wiki.csv
options courantes
- -F : désigne le séparateur de champs, par défaut il s'agit de l'espace
$ echo 'toto,titi' | awk -F ',' '{print $2}' titi
pour rappel : \\ \ \" " \a alert, ascii 7 \b backspace, ascii 8 \t tab, ascii 9 \n newline, ascii 10 \v vertical tab, ascii 11 \f formfeed, ascii 12 \r carriage return, ascii 13
- -f : permet de faire appel à un fichier texte contenant le script
# test.awk : { print $2 }
$ echo 'toto,titi' | awk -F ',' -f test.awk titi
- -v : indique une variable venant de l'extérieure
$ echo 'toto,titi' | awk -F ',' -v maVar="teste les variables" '{print $2 " " maVar}' titi teste les variables
utilisations
syntaxe générale
- De manière générale awk exécute pour chaque ligne les instructions contenu dans chaque bloc si les lignes et/ou éléments correspondent aux conditions, expressions, ... définis :
conditions et/ou regexp { instructions1 instructions2 ... } ...
- les blocs BEGIN et END
Ces deux blocs sont particuliers, ils permettent le traitement d'instructions avant et après l'exécution des blocs standards.
# exemples avec le fichier awk_wiki.csv BEGIN { ligne=0 } # match le champ 4 commençant par un G $4 ~ /^G/ { ligne+=1 } END { print "match : " ligne " ligne(s)" } # résultat : # match : 45 ligne(s)
exemples
Étant donné que le man 1 mawk contient tout ce dont vous avez besoin pour utiliser awk je vous laisse la consulter en parcourant ces exemples, j'essaierais tout de même de les commenter.
- Modification de notre fichier awk_wiki.csv
# ajout de la taille du champs 3 et 4 en début de ligne $ awk -F ',' '{result=length($3) "," length($4) "," $0; print result ; ligne++}' awk_wiki.csv > test2.csv
- Bon on se fait un peu chier là :(
nombre d'occurences
# exemple fichier test2.awk # initialisation des variables BEGIN { FS="," ligne=0 } # match des champ1 présent plus d'une fois dans le fichier !list[$1]++ { ligne++ } # pour toutes les lignes on compte le nombre d'occurrences des éléments de list # on stock le tout dans list2 { for (i in list) { if (i == $1) list2[i]+=1 } } # affichage des résultats END { for (i in list) print "$1 contient " list2[i] " fois la valeur " i print "------------------\n" ligne " valeurs uniques" } # resultat : awk -f test2.awk test2.csv # $1 contient 129 fois la valeur 10 # $1 contient 113 fois la valeur 11 # $1 contient 1 fois la valeur 3 # $1 contient 120 fois la valeur 4 # $1 contient 120 fois la valeur 5 # $1 contient 142 fois la valeur 6 # $1 contient 129 fois la valeur 7 # $1 contient 109 fois la valeur 8 # $1 contient 138 fois la valeur 9 # ------------------ # 9 valeurs uniques
- nombre d'occurences
On utilisera un fichier sous ce format :
data1 data2 data3 c1 c2 c3 c4 c5 e1 e2 1 < c < 50 et 1 < e < 9
{ # on rempli les listes c1[NR]=$4 c2[NR]=$5 c3[NR]=$6 c4[NR]=$7 c5[NR]=$8 e1[NR]=$9 e2[NR]=$10 } END { # on compte le nombre de 1, de 2, ... par liste i=0 while (i < 50) { i++ for (c in c1) { if (c1[c] == i) { liste1[i] = liste1[i]+1 } if (c2[c] == i) { liste2[i] = liste2[i]+1 } if (c3[c] == i) { liste3[i] = liste3[i]+1 } if (c4[c] == i) { liste4[i] = liste4[i]+1 } if (c5[c] == i) { liste5[i] = liste5[i]+1 } if (e1[c] == i) { liste6[i] = liste6[i]+1 } if (e2[c] == i) { liste7[i] = liste7[i]+1 } } } # impression du résultat i = 0 while (i < 50) { i++ print i "\t: " liste1[i] "\t" liste2[i] "\t" liste3[i] "\t" liste4[i] "\t" liste5[i] "\t" liste6[i] "\t" liste7[i] } }
Match et fonctions
# initialisation variables BEGIN { FS="," ligne=0 } # recherche de la ligne 901 à 910 FNR > 900 && FNR <= 910 { print FNR " " $0 "\n$4 : " $4 # recherche et remplace toutes les occurrences de "bg" dans le champ 4 gsub("bg", "#", $4) # utilisation du \ (\t : tab, \n : retour chariot, ...) print "gsub(\"bg\", \"#\", $4) : " $4 ; ligne++ } # retourne le nombre de lignes matchées END { print "lignes matchées : " ligne }
Un autre ?
# fichier awk_wiki.csv # recherche de la ligne 901 à 909 FNR > 900 && FNR < 910 { print $3 ligne++ } # champ 3 commence par G et champ 2 ne se terminant pas par A à L $3 ~ /^G/ && $2 !~ /[A-L]$/ { print $2 " " $3 ligne++ } # retourne le nombre de lignes matchées END { print "lignes matchées : " ligne }
Un dernier juste pour la syntaxe
# manipulation d'une liste # itération # commande system # variables awk : FILENAME, ARGV # awk -f fichier.awk fichier1.csv fichier2.csv BEGIN { FS = "," # just for fun :) for (i in ARGV) { print ARGV[i] print i } } (FILENAME == "fichier1.csv") { system("test -d /chemin/" $2 "> /tmp/test1") getline test1 < "/tmp/test1" system("rm /tmp/test1") if (test1 == 0) { lstLogin[$1] = "/chemin/" $2 } system("test -d /chemin/" $1 "> /tmp/test2") getline test2 < "/tmp/test2" system("rm /tmp/test2") if (test2 == 0) { lstLogin[$1] = "/chemin/" $1 } } (FILENAME == "fichier2.csv") { for (i in lstLogin) { if ($1 == i) { print lstLogin[i] " /chemin2/" $3 "/" $1 } } }
Liens externes
- la documentation en ligne de sed
- La documentation de gawk
- Je vous invite à visiter le très bon site d'Isabelle Vollant.
- Un lien complet pour les expressions régulières, sed et awk : softndesign
- Encore un petit lien pour sed ici